package fileoutputobjects;

import java.util.Random;

/**
 * This simulator moves at a constant velocity across the field of view. When the edge is reached, it's moved to another
 * edge, a new speed is calculated, and the simulation continues.
 * 
 * @author Trevor Terris
 *
 */
public class Drifter extends HumanSimulator
{
    //Sets the maximum speeds in each direction.
    //TODO: Set these values.
    private double myMaxXSpeed = 0.05;
    private double myMaxZSpeed = 0.05;
    
    private double myXVelocity, myZVelocity;
    private MutableInteger idObject;
    
    /**
     * The constructor. Takes the unique ID, then the amount that should be added to the ID to create a new ID when the 
     * original item hits an edge. This offset should be the number of total items being simlated.
     * 
     * @param thisID
     * @param IDIncrease
     */
    public Drifter (MutableInteger ID, Random r)
    {
        setRandom(r);
        setSpeeds();
        myID = ID.intValue();
        idObject = ID;
        ID.increment();
        setNewPositions();
    }
    
    /**
     * Randomly chooses a speed for the object.
     */
    private void setSpeeds()
    {
        myXVelocity = myRandom.nextDouble() * 2 * myMaxXSpeed - myMaxXSpeed;
        myZVelocity = myRandom.nextDouble() * 2 * myMaxZSpeed - myMaxZSpeed;
    }
    
    /**
     * Moves the object at a constant velocity. 
     */
    public void step()
    {
        myXCoord += myXVelocity;
        myZCoord += myZVelocity;
        
        //If it leaves the bounds, the method recalculate() is called.
        if (!isInBounds())
            recalculate();
    }
    
    /**
     * This method recalculates the object if it leaves the bounds. A new ID is created, 
     * then a side of the field is chosen for it to start moving in from.
     */
    private void recalculate()
    {
        int chooseSide = myRandom.nextInt(4);
        
        setNewPositions();
        setSpeeds();
        
        //creates a new ground-truth ID.
        myID = idObject.intValue();
        idObject.increment();
        
        /*After a new position and speed is randomly selected, they're adjusted, depending on what side they're on. 
         * X might be set to the minimum X value, which would mean that the X-component of the velocity would have 
         * to be positive, etc.*/
        switch(chooseSide) 
        {
            case 0: //The object starts from the rightmost edge
                myXCoord = myMinXValue; 
                myXVelocity = myRandom.nextDouble() * myMaxXSpeed;
                break;
            case 1: //The object starts from the leftmost edge
                myXCoord = myMaxXValue;
                myXVelocity = myRandom.nextDouble() * myMaxXSpeed * -1;
                break;
            case 2: //The object starts from the lower edge
                myZCoord = myMinZValue;
                myZVelocity = myRandom.nextDouble() * myMaxZSpeed;
                break;
            case 3: //The object starts from the upper edge
                myZCoord = myMaxZValue;
                myZVelocity = myRandom.nextDouble() * myMaxZSpeed * -1;
                break;
        }
    }
}
